package com.pandora.framework.util;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.dom4j.Element;

import com.alibaba.fastjson.JSONObject;
import com.pandora.common.aop.BusiBeanAOPBaseClass;
import com.pandora.common.business.UserOperatelogAddBusiness;
import com.pandora.common.exception.EduException;
import com.pandora.common.util.CommonUtils;
import com.pandora.common.util.StreamUtils;
import com.pandora.common.util.StringUtils;
import com.pandora.common.util.TimeUtils;
import com.pandora.common.util.WebUtils;
import com.pandora.framework.constant.Constants;
import com.pandora.framework.constant.ResponseConstants;
import com.pandora.framework.http.APIOperatelogVO;
import com.pandora.framework.vo.ServiceCoreVO;

/**
 * 请求服务工具类
 * 
 * @author JingChenglong 2017/12/20 14:50
 *
 */
public class ServiceUtils {

	/**
	 * 记录请求体响应日志
	 * 
	 * @param vo
	 */
	public static void operateLog(ServiceCoreVO vo) {
		new OperateLogThread(vo).start();
	}

	private static class OperateLogThread extends Thread {

		private APIOperatelogVO vo = null;

		@Override
		public void run() {
			super.run();
			BusiBeanAOPBaseClass aop = new BusiBeanAOPBaseClass();
			UserOperatelogAddBusiness business = (UserOperatelogAddBusiness)aop.bind(UserOperatelogAddBusiness.class);
			try {
				business.doBusiness(vo);
			} catch (EduException e) {
				e.printStackTrace();
			}
		}

		private OperateLogThread(ServiceCoreVO scvo) {

			vo = new APIOperatelogVO();
			vo.setType(scvo.getType());
			vo.setOperateLogNo(scvo.getOperateLogno());
			vo.setActionCode(StringUtils.nullToUnKnown(scvo.getAction()).toLowerCase());
			vo.setContent(getContent(scvo));

			vo.setStatus((ResponseConstants.SUCCESS == scvo.getCode() ? "1" : "2"));
			vo.setCode(String.valueOf(scvo.getCode()));

			String remark = PropertiesUtils.getCommonMessage(vo.getCode());
			if (StringUtils.isEmpty(remark) || Constants.UNKNOWN.equalsIgnoreCase(remark)) {
				remark = PropertiesUtils.getBusinessMessage(vo.getCode());
			}
			vo.setRemark((vo.getCode() + remark));

			vo.setRequestTime(scvo.getRequestTime());
			vo.setCompleteTime(TimeUtils.getSysTimeLong());

			vo.setIp(scvo.getIp());
			vo.setServiceType(scvo.getServiceType());
			vo.setRequestUrl(scvo.getRequestUrl());
			vo.setAccessid(scvo.getAccessid().toLowerCase());
			vo.setAccesskey(scvo.getAccesskey());
			vo.setSign(scvo.getSign());
			vo.setRecordNo(scvo.getRecordNo());

			scvo = null;
		}

		private String getContent(ServiceCoreVO vo) {

			StringBuffer sb = new StringBuffer();
			if (StringUtils.isNotEmpty(vo.getFormat())) {
				sb.append(";format->").append(StringUtils.nullToStrTrim(vo.getFormat()));
			}
			if (vo.getReqlength() > 0) {
				sb.append(";reqlength->").append(vo.getReqlength());
			}
			if (StringUtils.isNotEmpty(vo.getSign())) {
				sb.append(";sign->").append(StringUtils.nullToStrTrim(vo.getSign()));
			}
			if (StringUtils.isNotEmpty(vo.getReqcontentmd5())) {
				sb.append(";reqcontentmd5->").append(StringUtils.nullToStrTrim(vo.getReqcontentmd5()));
			}
			if (StringUtils.isNotEmpty(vo.getRequestTime())) {
				sb.append(";requesttime->").append(StringUtils.nullToStrTrim(vo.getRequestTime()));
			}
			if (StringUtils.isNotEmpty(vo.getReqContent())) {
				sb.append(";reqcontent->").append(StringUtils.removeBlank(vo.getReqContent()));
			}
			if (StringUtils.isNotEmpty(vo.getException())) {
				sb.append(";exception->{").append(vo.getCode()).append("-")
						.append(StringUtils.nullToStrTrim(vo.getException())).append("}");
			}

			return sb.length() > 0 ? sb.substring(1) : sb.toString();
		}
	}

	/**
	 * 获取请求体内容中的指定key的信息
	 * 
	 * @param reqObject
	 * @param key
	 */
	public static String getRequestContentValue(Object reqContent, String key) throws EduException {

		if (reqContent == null) {
			throw new EduException(ResponseConstants.REQUEST_CONTENT_ERROR);
		}

		String value = "";

		if (reqContent instanceof Element) {
			value = StringUtils.nullToStrTrim(((Element) reqContent).attributeValue(key));
		} else if (reqContent instanceof JSONObject) {
			value = StringUtils.nullToStrTrim(((JSONObject) reqContent).getString(key));
		} else {
			throw new EduException(ResponseConstants.REQUEST_CONTENT_ERROR);
		}

		return value;
	}

	/**
	 * 响应体设置
	 * 
	 * @param response
	 * @param resContent
	 */
	public static void responseContent(HttpServletResponse response, String resContent) {

		response.setCharacterEncoding(Constants.ENCODING_UTF8);
		response.setContentType("application/octet-stream");
		response.setContentLength(StringUtils.getRealLength(resContent));

		OutputStream outputStream = null;
		BufferedOutputStream bufferedOutputStream = null;

		try {
			outputStream = response.getOutputStream();
			bufferedOutputStream = new BufferedOutputStream(outputStream);

			bufferedOutputStream.write(resContent.getBytes(Constants.ENCODING_UTF8));

			StreamUtils.flush(bufferedOutputStream);

			WebUtils.flushBuffer(response);
		} catch (IOException e) {
			LogUtils.logError(CommonUtils.getTraceInfo() + e.getMessage());
		} finally {
			StreamUtils.closeBufferedOutputStream(bufferedOutputStream);
			StreamUtils.closeOutputStream(outputStream);
		}
	}

	/**
	 * 判断是否为相应码
	 * 
	 * @param code
	 * @return
	 */
	public static boolean isInfoCode(String code) {

		code = StringUtils.nullToStrTrim(code);
		if (code.length() != 6) {
			return false;
		}

		return code.matches("^([1-9])\\d{5}$");
	}
}